package com.pap.logback.builder;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.OptionHelper;

/**
 * 在运行时，动态创建日志文件，特别是文件名根据某些参数决定。这种方式只能通过编程方式来实现
 * 	
 * 需要注意，我们通常在日志文件路径上使用使用一些系统变量（比如${catalina.base}）、或者logback.xml配置的properties；
 * 此时我们可以使用OptionHelper辅助类来替换String中的变量占位符，此外LoggerContext中包含logback.xml配置的properties。
 * 不过这些properties默认上下文Scope为“local”，如果想让它们能够被LoggerContext访问，需要强制设置为“context”。
 * 
 * 	logback.xml
 * 	<property scope="context" name="LOG_PATH" value="${catalina.base}/logs"/>
 * @author alexgaoyh
 *
 */
public class LogbackLoggerBuilder {

	private static final Map<String, Logger> container = new HashMap<>();

	public static Logger getLogger(String name) {
		Logger logger = container.get(name);
		if (logger != null) {
			return logger;
		}
		synchronized (LogbackLoggerBuilder.class) {
			logger = container.get(name);
			if (logger != null) {
				return logger;
			}
			logger = build(name);
			container.put(name, logger);
		}
		return logger;
	}

	private static Logger build(String name) {
		LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
		Logger logger = context.getLogger("FILE-" + name);
		logger.setAdditive(false);
		RollingFileAppender appender = new RollingFileAppender();
		appender.setContext(context);
		appender.setName("FILE-" + name);
		appender.setFile(OptionHelper.substVars("${LOG_PATH}/log-" + name + ".log", context));
		appender.setAppend(true);
		appender.setPrudent(false);
		SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy();
		String fp = OptionHelper.substVars("${LOG_PATH}/log-" + name + ".log.%d{yyyy-MM-dd}.%i", context);

		policy.setMaxFileSize(FileSize.valueOf("32MB"));
		policy.setFileNamePattern(fp);
		// 日志文件保留天数
		policy.setMaxHistory(7);
		// 所有日志文件的大小
		policy.setTotalSizeCap(FileSize.valueOf("2GB"));
		policy.setParent(appender);
		policy.setContext(context);
		policy.start();

		PatternLayoutEncoder encoder = new PatternLayoutEncoder();
		encoder.setContext(context);
		encoder.setPattern("%d{yyyy-MM-dd/HH:mm:ss.SSS}|%X{localIp}|[%t] %-5level %logger{0} %line - %m%n");
		encoder.start();

		appender.setRollingPolicy(policy);
		appender.setEncoder(encoder);
		appender.start();
		logger.addAppender(appender);
		return logger;
	}
}
